package com.yanqu.road.dao.impl.activity.springdinner;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.db.DbParameter;
import com.yanqu.road.dao.impl.TempDataObjectDao;
import com.yanqu.road.entity.activity.springdinner.BallData;
import com.yanqu.road.entity.activity.springdinner.SpringDinnerUserData;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SpringDinnerUserDataDaoImpl extends TempDataObjectDao<SpringDinnerUserData> {

    public static String getUserDataSql = "select * from t_u_activity_spring_dinner where activityId=? and userId=?";
    public SpringDinnerUserData getUserData(int activityId, long userId) {
        ResultSet rs = null;
        CallableStatement call = null;
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(getUserDataSql);
            int i = 1;
            call.setInt(i++,activityId);
                call.setLong(i++,userId);
                rs = call.executeQuery();
                while (rs.next()) {
                    SpringDinnerUserData data = parse(rs);
                return data;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);} finally {
            getDb().closeConnection(call, rs);
        }
        return null;
    }

    public static String insertUserDataSql = "insert into t_u_activity_spring_dinner(" +
            "activityId,userId,integral,nextBallData,ballCountData,ballData,stepData,updateTime,hp,hpTime,mergeData,gameNoData,clearData,integralData,hasMeiTuanNotice,shareCount,shareResetTime,currentIntegralMap,gameStatusMap) " +
            " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    @Override
    protected boolean addData(SpringDinnerUserData data) {
        data.setBeginWriteTime();
        getDb().setConnName(DbNameStrategy.getUserDb());
        int i = 1;
        Map<Integer, DbParameter> para = new HashMap<Integer, DbParameter>();
        para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
        para.put(i++, new DbParameter(Types.VARCHAR, data.getIntegral().toString()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getNextBallMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getBallCountMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getBallMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getStepMap())));
        para.put(i++, new DbParameter(Types.BIGINT, data.getUpdateTime()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getHp()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getHpTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getMergeMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getGameNoMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getClearMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getIntegralMap())));
        para.put(i++, new DbParameter(Types.BOOLEAN, data.isHasMeiTuanNotice()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getShareCount()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getShareResetTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getCurrentIntegralMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getGameStatusMap())));
        if (getDb().executeNoneQuery(insertUserDataSql, para) > 0) {
            return true;
        }
        return false;
    }

    public static String updateUserDataSql = "update t_u_activity_spring_dinner set integral=?,nextBallData=?,ballCountData=?," +
            "updateTime=?,ballData=?,hp=?,hpTime=?,stepData=?,mergeData=?,gameNoData=?,clearData=?,integralData=?,hasMeiTuanNotice=?,shareCount=?,shareResetTime=?,currentIntegralMap=?,gameStatusMap=? " +
            " where activityId=? and userId=?";
    @Override
    protected boolean updateData(SpringDinnerUserData data) {
        data.setBeginWriteTime();
        getDb().setConnName(DbNameStrategy.getUserDb());
        int i = 1;
        Map<Integer, DbParameter> para = new HashMap<Integer, DbParameter>();
        para.put(i++, new DbParameter(Types.VARCHAR, data.getIntegral().toString()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getNextBallMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getBallCountMap())));
        para.put(i++, new DbParameter(Types.BIGINT, data.getUpdateTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getBallMap())));
        para.put(i++, new DbParameter(Types.INTEGER, data.getHp()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getHpTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getStepMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getMergeMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getGameNoMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getClearMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getIntegralMap())));
        para.put(i++, new DbParameter(Types.BOOLEAN, data.isHasMeiTuanNotice()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getShareCount()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getShareResetTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getCurrentIntegralMap())));
        para.put(i++, new DbParameter(Types.VARCHAR, JSONArray.toJSONString(data.getGameStatusMap())));

        para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
        if (getDb().executeNoneQuery(updateUserDataSql, para) > 0) {
            return true;
        }
        return false;
    }

    @Override
    protected SpringDinnerUserData parseData(ResultSet rs) throws SQLException {
        SpringDinnerUserData data = new SpringDinnerUserData();
        data.setActivityId(rs.getInt("activityId"));
        data.setUserId(rs.getLong("userId"));
        data.setIntegral(new BigInteger(rs.getString("integral")));
        data.setUpdateTime(rs.getLong("updateTime"));
        data.setHp(rs.getInt("hp"));
        data.setHpTime(rs.getLong("hpTime"));

        String nextBallStr  = rs.getString("nextBallData");
        if(!StringUtils.isNullOrEmpty(nextBallStr)){
            Map<Integer, BallData> result = JSON.parseObject(nextBallStr, new TypeReference<Map<Integer, BallData>>() {});
            if(result != null){
                data.setNextBallMap(result);
            }
        }
        String countStr  = rs.getString("ballCountData");
        if(!StringUtils.isNullOrEmpty(countStr)){
            Map<Integer, Integer> result = JSON.parseObject(countStr, new TypeReference<Map<Integer, Integer>>() {});
            if(result != null){
                data.setBallCountMap(result);
            }
        }
        String str  = rs.getString("ballData");
        if(!StringUtils.isNullOrEmpty(str)){
            Map<Integer, Map<Integer,BallData>> result = JSON.parseObject(str, new TypeReference<Map<Integer, Map<Integer,BallData>>>() {});
            if(result != null){
                data.setBallMap(result);
            }
        }
        String stepStr  = rs.getString("stepData");
        if(!StringUtils.isNullOrEmpty(stepStr)){
            Map<Integer, Integer> result = JSON.parseObject(stepStr, new TypeReference<Map<Integer, Integer>>() {});
            if(result != null){
                data.setStepMap(result);
            }
        }
        String mergeStr  = rs.getString("mergeData");
        if(!StringUtils.isNullOrEmpty(mergeStr)){
            Map<Integer, Map<Integer,Integer>> result = JSON.parseObject(mergeStr, new TypeReference<Map<Integer, Map<Integer,Integer>>>() {});
            if(result != null){
                data.setMergeMap(result);
            }
        }
        String gameNoStr  = rs.getString("gameNoData");
        if(!StringUtils.isNullOrEmpty(gameNoStr)){
            Map<Integer, Integer> result = JSON.parseObject(gameNoStr, new TypeReference<Map<Integer,Integer>>() {});
            if(result != null){
                data.setGameNoMap(result);
            }
        }
        String clearStr  = rs.getString("clearData");
        if(!StringUtils.isNullOrEmpty(clearStr)){
            Map<Integer, Integer> result = JSON.parseObject(clearStr, new TypeReference<Map<Integer,Integer>>() {});
            if(result != null){
                data.setClearMap(result);
            }
        }
        String integralStr  = rs.getString("integralData");
        if(!StringUtils.isNullOrEmpty(integralStr)){
            Map<Integer, Long> result = JSON.parseObject(integralStr, new TypeReference<Map<Integer,Long>>() {});
            if(result != null){
                data.setIntegralMap(result);
            }
        }
        data.setHasMeiTuanNotice(rs.getBoolean("hasMeiTuanNotice"));
        data.setShareCount(rs.getInt("shareCount"));
        data.setShareResetTime(rs.getLong("shareResetTime"));
        String currentIntegralMap  = rs.getString("currentIntegralMap");
        if(!StringUtils.isNullOrEmpty(currentIntegralMap)){
            Map<Integer, BigInteger> result = JSON.parseObject(currentIntegralMap, new TypeReference<ConcurrentHashMap<Integer, BigInteger>>() {

            });
            if(result != null){
                data.setCurrentIntegralMap(result);
            }
        }
        String gameStatusMap = rs.getString("gameStatusMap");
        if(!StringUtils.isNullOrEmpty(gameStatusMap)){
            Map<Integer, Boolean> result = JSON.parseObject(gameStatusMap, new TypeReference<Map<Integer, Boolean>>() {});
            if(result != null){
                data.setGameStatusMap(result);
            }
        }
        return data;
    }

}
